package cn.newzai

import org.kohsuke.args4j._
import cn.newzai.parser.proto.GoogleProtobufParser
import cn.newzai.util.WriteFile



object Main {

  @Option(name="-d",  usage ="input dir")
  var dir :String = null

  @Option(name="-f",  usage="proto file name")
  var protoFile :String = null

  @Option(name="-c", usage = "proto file encoding,such as UTF-8,UTF-8,GBK")
  var encoding = "UTF-8"

  @Option(name="-xaml", usage = "generate xaml file")
  var gen_xaml = false

  @Option(name="-xamldir",usage="xaml file output dir.")
  var xaml_out_idr  :String = null

  @Option(name="-csharp" ,usage="generate charp code.")
  var gen_csharp = false

  @Option(name="-csharpdir", usage="*.cs file output dir.")
  var csharp_out_dir  :String = null

  @Option(name="-scala", usage="generate scala code.")
  var gen_scala = false

  @Option(name="-convert", usage="generate IValueConverter Code for C#")
  var gen_convert = false

  @Option(name="-csharpns", usage =" Set CSharp namespace..")
  var csharp_namespace = "MyProject"

  @Option(name="-help" ,usage="show help.")
  var help= false


  @Argument
  var arguments = new java.util.ArrayList[String]()

  val helpStr ="""
                 |参数: -d dir -f file [-c encoding] [ -xaml ] [-xamldir dir] [ -csharp] [ -csharpdir dir] [-scala]  [-convert] [-csharpns]
                 |
                 | -d 文件夹
                 | -f proto文件名
                 | -c proto文件编码，默认UTF-8格式
                 | -xaml 指定生成xaml文件。为每个消息生成一个文件，
                 | -xamldir 输出目录。默认为与-d相同
                 | -charp 指定生成C#代码。
                 | -csharpdir C#代码文件输出目录。默认与-d相同
                 | -slcal    指定生成Scala代码
                 | -convert 为枚举生成基于C#的转换代码，实现IValueConverter接口，为WPF（Silverlight）所使用.
                 | -csharpns CSharp 代码的名称空间
                 | """.stripMargin

    def main( args : Array[String]) {


      val parser = new CmdLineParser(this)

      parser.setUsageWidth(80)
      try{
        import scala.collection.convert.wrapAsJava.asJavaCollection
        parser.parseArgument( asJavaCollection(args) )


        if( help ){

          println("帮助信息:")
          println(helpStr)
        } else
        {
          if( dir == null || dir == ""){
            dir = "."
          }
          val gparser = new GoogleProtobufParser(dir,protoFile,encoding)
          val r = gparser.parserFile
          if ( r.successful ){
         import cn.newzai.parser.proto.result._

            if( xaml_out_idr == null || xaml_out_idr == ""){
              xaml_out_idr = s"${dir}\\xaml"

            }
            if( csharp_out_dir == null || csharp_out_dir ==""){
              csharp_out_dir = dir
            }
          //val codes = Message.message.map( _.generate_code(GenerateCodeType.XamlCode)).mkString("\n")
          if( gen_xaml)
          {
            println("gen xaml")
            Message.message.foreach{
              m =>


                WriteFile.write(s"${xaml_out_idr}\\User${m.name}.xml", m.generate_code(GenerateCodeType.XamlCode))
                WriteFile.write(s"${xaml_out_idr}\\SilverlightControl${m.name}.xml", m.generate_code(GenerateCodeType.XamlCodeLiner))
            }
          }
          if( gen_csharp)
          {
            println("gen_chsarp")

            val codes = Message.message.map( _.generate_code(GenerateCodeType.CSharpCode)).mkString("\n")
            val filecodes =
              s"""
                |using System;
                |using System.ComponentModel;
                |using System.Collections.ObjectModel;
                |using System.Text;
                |using DBCSCodePage;
                |namespace ${csharp_namespace}
                |{
                | public class Notify : INotifyPropertyChanged
                | {
                |   public event PropertyChangedEventHandler PropertyChanged;
                |   public void OnPropertyChanged( string attrName)
                |   {
                |     if ( PropertyChanged != null )
                |     {
                |       PropertyChanged(this, new PropertyChangedEventArgs(attrName));
                |     }
                |   }
                | }
                |
                |${codes}
                |}
              """.stripMargin
            WriteFile.write(s"${csharp_out_dir}\\${protoFile}.cs",filecodes)
          }

          if( gen_convert )
          {

            val codes = Enum.generate_convert();
            WriteFile.write(s"${csharp_out_dir}\\${protoFile}.convert.cs",codes);
            println("gen_csharp_convert")

            WriteFile.write(s"${csharp_out_dir}\\${protoFile}.resource.xml", Enum.generate_resource())

            println("gen resource")

            Enum.generate_combox(xaml_out_idr)
            println("gen enum combox")

            Enum.generate_radio(xaml_out_idr)
            println("gen enum radio group.")
          }
        } else {
            println(r)
          }
        }
      }catch{
        case e : Exception =>
          print("Exception:")
          println(e.getMessage)
          println(e.getStackTrace)
          println(helpStr)
      }
    }
}
